#include<string>
#include<vector>
#include<array>
#include<unordered_map>
#include<algorithm>
#include<limits>
#include <stack>
#include<iostream>
#include<sstream>
#include<deque>
#include <vector>
using namespace std;

class Solution {
public:
    static const int MAXN = 100001;
    
    // 窗口内最大值的更新结构（单调队列）
    int maxDeque[MAXN];
    
    // 窗口内最小值的更新结构（单调队列）
    int minDeque[MAXN];
    
    int maxh, maxt, minh, mint;
    vector<int> arr;

    int longestSubarray(vector<int>& nums, int limit) {
        maxh = maxt = minh = mint = 0;
        arr = nums;
        int n = arr.size();
        int ans = 0;
        for (int l = 0, r = 0; l < n; l++) {
            // [l,r)，r永远是没有进入窗口的、下一个数所在的位置
            while (r < n && ok(limit, arr[r])) {
                push(r++);
            }
            // 从while出来的时候，[l,r)是l开头的子数组能向右延伸的最大范围
            ans = max(ans, r - l);
            pop(l);
        }
        return ans;
    }

    // 判断如果加入数字number，窗口最大值 - 窗口最小值是否依然 <= limit
    // 依然 <= limit，返回true
    // 不再 <= limit，返回false
    bool ok(int limit, int number) {
        // max : 如果number进来，新窗口的最大值
        int maxA = maxh < maxt ? max(arr[maxDeque[maxh]], number) : number;
        // min : 如果number进来，新窗口的最小值
        int minA = minh < mint ? min(arr[minDeque[minh]], number) : number;
        return maxA - minA <= limit;
    }

    // r位置的数字进入窗口，修改窗口内最大值的更新结构、修改窗口内最小值的更新结构
    void push(int r) {
        while (maxh < maxt && arr[maxDeque[maxt - 1]] <= arr[r]) {
            maxt--;
        }
        maxDeque[maxt++] = r;
        while (minh < mint && arr[minDeque[mint - 1]] >= arr[r]) {
            mint--;
        }
        minDeque[mint++] = r;
    }

    // 窗口要吐出l位置的数了！检查过期！
    void pop(int l) {
        if (maxh < maxt && maxDeque[maxh] == l) {
            maxh++;
        }
        if (minh < mint && minDeque[minh] == l) {
            minh++;
        }
    }
};